import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileNameExtensionFilter;

import java.awt.SystemColor;
import java.text.DecimalFormat;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JTextField;
import javax.swing.JLabel;
import java.awt.Font;
import java.awt.Color;

import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.SwingConstants;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;


public class boggleMainGame extends JFrame {

	private JPanel contentPane;
	private boggleGame currentBoggleGame;
	private letter[][] letterArray;
	private JTextField guessTextField;

	private JList guessList;
	private DefaultListModel guessListModel;

	private JLabel playerLabel;
	private JLabel timeLabel;

	private Boolean isPaused;

	private Timer timer;

	public boggleMainGame(boggleGame currentGame){
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 870, 580);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		setLocationRelativeTo(null);
		setTitle("Boggle");
		setResizable(false);
		this.currentBoggleGame = currentGame;

		isPaused = true;

		setVisible(true);

		//Boggle Board
		{
			//JPanel
			JPanel boggleBoardPanel = new JPanel();
			boggleBoardPanel.setBackground(SystemColor.inactiveCaption);
			boggleBoardPanel.setBounds(10, 11, 500, 500);
			contentPane.add(boggleBoardPanel);

			boggleBoardPanel.setLayout(new GridLayout(currentBoggleGame.getCurrentBoard().getBoardSize(), currentBoggleGame.getCurrentBoard().getBoardSize(), 0, 0));

			//Add Letters to board
			letterArray = new letter[currentBoggleGame.getCurrentBoard().getBoardSize()][currentBoggleGame.getCurrentBoard().getBoardSize()];
			int i = 0;	int j = 0;
			for(Character[] letters : currentBoggleGame.getCurrentBoard().getLetters()){
				for(Character let : letters){
					letterArray[i][j] = new letter(let);
					boggleBoardPanel.add(letterArray[i][j]);
					j++;
				}
				j = 0;
				i++;
			}
		}

		//Stats
		{
			//Current Player
			playerLabel = new JLabel("Player: ");
			playerLabel.setFont(new Font("Tahoma", Font.BOLD, 16));
			playerLabel.setBounds(520, 11, 283, 32);
			contentPane.add(playerLabel);

			//Time Left
			timeLabel = new JLabel("Time Left: ");
			timeLabel.setFont(new Font("Tahoma", Font.BOLD, 16));
			timeLabel.setBounds(710, 13, 148, 29);
			contentPane.add(timeLabel);

			//Stats Label
			JLabel statsLabel = new JLabel("Stats:");
			statsLabel.setFont(new Font("Tahoma", Font.BOLD, 16));
			statsLabel.setBounds(520, 42, 283, 32);
			contentPane.add(statsLabel);

			//Stats Area
			JTextArea statsArea = new JTextArea();
			statsArea.setFont(new Font("Monospaced", Font.BOLD, 13));
			statsArea.setEditable(false);
			statsArea.setBounds(520, 70, 338, 175);
			contentPane.add(statsArea);

			//Get Stats
			int[] wordStats = currentBoggleGame.getWordStats();
			StringBuilder boggleStats = new StringBuilder();
			boggleStats.append("Available Words:\n");
			boggleStats.append(String.format("3-4 Letters: %d (1 pt)\n", wordStats[0]));
			boggleStats.append(String.format("5 Letters: %d (2 pts)\n", wordStats[1]));
			boggleStats.append(String.format("6 Letters: %d (3 pts)\n", wordStats[2]));
			boggleStats.append(String.format("7 Letters: %d (5 pts)\n", wordStats[3]));
			boggleStats.append(String.format("8 Letters: %d (11 pts)\n", wordStats[4]));
			boggleStats.append(String.format("9 Letters: %d (2 pts/letter)\n\n", wordStats[5]));
			boggleStats.append(String.format("Total Words: %d", currentBoggleGame.getExistingWords().size()));
			statsArea.setText(boggleStats.toString());
		}

		//Guess Text Field
		{
			//Guess Label
			JLabel guessLabel = new JLabel("Guesses:");
			guessLabel.setFont(new Font("Tahoma", Font.BOLD, 16));
			guessLabel.setBounds(520, 256, 142, 29);
			contentPane.add(guessLabel);

			//Guess List
			guessListModel = new DefaultListModel();
			guessList = new JList(guessListModel);
			guessList.setFont(new Font("Tahoma", Font.BOLD, 11));
			guessList.setBounds(520, 284, 243, 258);
			contentPane.add(guessList);

			//Scroll Bar
			final JScrollPane guessScroll = new JScrollPane(guessList);
			guessScroll.setBounds(guessList.getBounds());
			getContentPane().add(guessScroll);

			//Text Field
			guessTextField = new JTextField();
			guessTextField.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					if(!guessTextField.getText().trim().isEmpty()){
						currentBoggleGame.getPlayers().get(currentBoggleGame.getCurrentPlayer()).addGuessedWord(guessTextField.getText().trim());
						guessTextField.setText("");
						guessListModel.clear();
						for(String guess : currentBoggleGame.getPlayers().get(currentBoggleGame.getCurrentPlayer()).getGuessedWords()){
							guessListModel.addElement(guess);
						}
						guessScroll.getVerticalScrollBar().setValue(guessScroll.getVerticalScrollBar().getMaximum());
					}
				}
			});
			guessTextField.setBounds(10, 522, 500, 20);
			contentPane.add(guessTextField);
			guessTextField.setColumns(10);

		}

		//Buttons
		{
			//Give Up
			JButton giveUp = new JButton("Give Up");
			giveUp.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					isPaused = true;
					if(JOptionPane.showConfirmDialog(null, "Give Up?", "Give Up?", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION){
						currentBoggleGame.setTimeRemaining(0);

						//Reset Guess
						for(int i = 0; i < currentBoggleGame.getCurrentBoard().getBoardSize(); i++){
							for(int j = 0; j < currentBoggleGame.getCurrentBoard().getBoardSize(); j++){
								letterArray[i][j].setHighlight(false);
							}
						}
						guessTextField.setText("");
					}
					isPaused = false;
				}
			});
			giveUp.setBounds(768, 284, 90, 80);
			contentPane.add(giveUp);

			//Main Menu
			JButton mainMenu = new JButton("<html>\r\n<p align=\"center\">\r\nMain<br>\r\nMenu\r\n</p>\r\n</html>");
			mainMenu.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					isPaused = true;
					if(JOptionPane.showConfirmDialog(null, "Quit game and return to main menu?", "Give Up?", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION){
						timer.cancel();
						mainMenu menu = new mainMenu();
						menu.setVisible(true);
						dispose();
					}
					isPaused = false;
				}
			});
			mainMenu.setBounds(768, 375, 90, 80);
			contentPane.add(mainMenu);

			//Save and Quit
			JButton saveAndQuit = new JButton("<html>\r\n<p align=\"center\">\r\nSave<br>\r\nAnd<br>\r\nQuit\r\n</p>\r\n</html>");
			saveAndQuit.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					isPaused = true;
					JFileChooser chooser = new JFileChooser();
					chooser.setFileFilter(new FileNameExtensionFilter("XML Files", "xml"));
					if(chooser.showSaveDialog(getParent()) == chooser.APPROVE_OPTION){
						timer.cancel();
						currentBoggleGame.saveGame(chooser.getSelectedFile().getAbsolutePath().replace(".xml", "") + ".xml");
						mainMenu menu = new mainMenu();
						menu.setVisible(true);
						dispose();
					}
					isPaused = false;
				}
			});
			saveAndQuit.setBounds(768, 462, 90, 80);
			contentPane.add(saveAndQuit);
		}

		//Load Data
		loadData();

		//Timer
		{
			timer = new Timer();
			timer.schedule(highlighter, 1, 1);
			timer.schedule(gameTimer, 1, 1000);
		}
	}

	//Game Timer
	TimerTask gameTimer = new TimerTask(){
		public void run() {
			if(!isPaused){
				if(currentBoggleGame.getTimeRemaining() >= 1){
					currentBoggleGame.setTimeRemaining(currentBoggleGame.getTimeRemaining() - 1);
					timeLabel.setText("Time: " + currentBoggleGame.getTimeRemaining() / 60 + ":" + new DecimalFormat("00").format(currentBoggleGame.getTimeRemaining() % 60));
				}else{
					if(currentBoggleGame.getCurrentPlayer() + 1 < currentBoggleGame.getPlayers().size()){
						currentBoggleGame.setCurrentPlayer(currentBoggleGame.getCurrentPlayer() + 1);
						currentBoggleGame.resetTime();
						loadData();
					}else if(currentBoggleGame.getCurrentPlayer() + 1 == currentBoggleGame.getPlayers().size()){
						timer.cancel();
						JOptionPane.showMessageDialog(getParent(),"Game Finished!");
						showResults();
					}
				}
			}
		}
	};

	//Highlighter
	TimerTask highlighter = new TimerTask() {
		public void run() {
			if(!guessTextField.getText().isEmpty()){
				if(!(guessTextField.getText().length() == currentBoggleGame.getCurrentBoard().wordExists(guessTextField.getText(), true))){
					guessTextField.setText(guessTextField.getText().substring(0, guessTextField.getText().length() - 1));
					guessTextField.setCaretPosition(guessTextField.getText().length());
				}
				else{
					for(int i = 0; i < currentBoggleGame.getCurrentBoard().getBoardSize(); i++){
						for(int j = 0; j < currentBoggleGame.getCurrentBoard().getBoardSize(); j++){
							letterArray[i][j].setHighlight(currentBoggleGame.getCurrentBoard().getPassedLetters()[i][j]);
						}
					}
				}
			}else{
				for(int i = 0; i < currentBoggleGame.getCurrentBoard().getBoardSize(); i++){
					for(int j = 0; j < currentBoggleGame.getCurrentBoard().getBoardSize(); j++){
						letterArray[i][j].setHighlight(false);
					}
				}
			}
		}
	};

	//Load Player Data
	private void loadData(){
		guessListModel.clear();
		playerLabel.setText("Player: " + currentBoggleGame.getPlayers().get(currentBoggleGame.getCurrentPlayer()).getName());
		timeLabel.setText("Time: " + currentBoggleGame.getTimeRemaining() / 60 + ":" + new DecimalFormat("00").format(currentBoggleGame.getTimeRemaining() % 60));
		for(String guess : currentBoggleGame.getPlayers().get(currentBoggleGame.getCurrentPlayer()).getGuessedWords()){
			guessListModel.addElement(guess);
		}
		JOptionPane.showMessageDialog(getParent(),String.format("%s's turn", currentBoggleGame.getPlayers().get(currentBoggleGame.getCurrentPlayer()).getName()));
		isPaused = false;
	}

	//Show Results
	private void showResults(){
		resultsScreen results = new resultsScreen(currentBoggleGame);
		results.setVisible(true);
		dispose();
	}
}
